/**
 * 
 */
package com.pmsco.pms.interceptor;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.pmsco.pms.annotation.LogonRequired;
import com.pmsco.pms.annotation.PermissionRequired;
import com.pmsco.pms.core.constant.PmsConstant;
import com.pmsco.pms.core.domain.PmsPermissionRole;
import com.pmsco.pms.services.impl.PmsPermissionRoleServiceImpl;
import com.pmsco.pms.util.PmsLogonRequired;
import com.pmsco.pms.util.PmsPermissionRequired;
import com.pmsco.pms.util.PmsUserRole;
import com.pmsco.pms.util.PmsUserSession;

/**
 * @author Tran Thanh Long
 *
 */
public class LoginInterceptor implements HandlerInterceptor {
	@Override
	public void afterCompletion(HttpServletRequest arg0,
			HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
	}

	@Override
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
			Object arg2, ModelAndView arg3) throws Exception {
	}

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse respone,
			Object handler) throws Exception {
		System.out.println("Intercepting: " + request.getRequestURI());
		System.out.println(handler.toString());
		try {
			HandlerMethod method = (HandlerMethod) handler;
			LogonRequired logonAnnotation = method.getMethodAnnotation(LogonRequired.class);
			if(logonAnnotation != null) {
				PmsLogonRequired logonReqired = logonAnnotation.required();
				System.out.println("Required logon under role: " + logonReqired.name());

				PmsUserSession pmsUserSession = (PmsUserSession)request.getSession().getAttribute(PmsConstant.loggedUserSession);
				if(pmsUserSession != null) {
					System.out.println("User name: " + pmsUserSession.getUserName());
					System.out.println("Role: " + pmsUserSession.getUserRole());
					System.out.println("Session id: " + pmsUserSession.getSessionId());
					PermissionRequired permissionAnnotation = method.getMethodAnnotation(PermissionRequired.class);
					if(permissionAnnotation != null) {
						boolean canAccess = checkPermission(permissionAnnotation.required(), pmsUserSession.getUserRole());
						if(!canAccess && pmsUserSession.getUserRole().compareTo(PmsUserRole.ADMIN_USER) == 0) {
							respone.sendRedirect(PmsConstant.invalidRoleA_JspUrl);
						} else if(!canAccess) {
							respone.sendRedirect(PmsConstant.invalidRoleU_JspUrl);
						}
					}
				} else {
					if(logonReqired.equals(PmsLogonRequired.ADMIN_USER))
						respone.sendRedirect(PmsConstant.admin_JspUrl);
					else if (logonReqired.equals(PmsLogonRequired.NORMAL_USER))
						respone.sendRedirect(PmsConstant.userLogon_JspUrl);
				}
			}
		} catch (ClassCastException e) {
			System.out.println("Exception when casting " + e.getMessage());
		}
		return true;
	}
	
	private boolean checkPermission(PmsPermissionRequired pmsPermissionRequired, PmsUserRole pmsUserRole) {
		boolean ret = false;
		PmsPermissionRoleServiceImpl pmsPermissionRoleService = new PmsPermissionRoleServiceImpl();
		List<PmsPermissionRole> permissionRoles = pmsPermissionRoleService.loadPmsPermissionRoleByName(pmsPermissionRequired.name());
		for(PmsPermissionRole permissionRole : permissionRoles) {
			PmsUserRole role = PmsUserRole.getPmsUserRole(permissionRole.getRole().getRole());
			if(role.compareTo(pmsUserRole) == 0)
				ret = true;
		}
		return ret;
	}

}
